import json
from user.models import *
import pytz
from django.db.models import Q
from random import sample
from django.db import connections
from django_system.role_recognize import check_permission
from django.http import JsonResponse
from django.views import View
from .models import *
from django.utils.decorators import method_decorator


class AddQuestions(View):
    """
    添加题目
    """

    def get(self, request):
        questions_type = QuestionType.objects.all().values()
        return JsonResponse(data={'questions_type': list(questions_type), 'code': 200, 'msg': '获取试题分类成功'})

    @method_decorator(check_permission(['老师']))
    def post(self, request):
        data = json.loads(request.body)
        q_type = QuestionType.objects.get(id=data['question_type'])
        if not data['title']:
            return JsonResponse(data={'code': 401, 'msg': '标题不能为空'})
        if data['question_type'] == 1:
            if not all([data['answer'], data['options']]):
                return JsonResponse(data={'code': 403, 'msg': '答案和选项不能为空'})
            try:
                TestQuestions.objects.create(question_type=q_type, title=data['title'],
                                             answer=json.dumps([data['answer']], ensure_ascii=False),
                                             options=json.dumps(data['options'], ensure_ascii=False))
                return JsonResponse(data={'code': 201, 'msg': '添加成功'})
            except Exception as e:
                return JsonResponse(data={'code': 401, 'msg': f'添加失败原因是{e}'})
        if data['question_type'] == 2:
            if not all([data['answers'], data['options']]):
                return JsonResponse(data={'code': 403, 'msg': '答案和选项不能为空'})
            try:
                TestQuestions.objects.create(question_type=q_type, title=data['title'],
                                             answer=json.dumps(data['answers'], ensure_ascii=False),
                                             options=json.dumps(data['options'], ensure_ascii=False))
                return JsonResponse(data={'code': 201, 'msg': '添加成功'})
            except Exception as e:
                return JsonResponse(data={'code': 401, 'msg': f'添加失败原因是{e}'})
        if data['question_type'] in [3, 4]:
            if not all([data['answer']]):
                return JsonResponse(data={'code': 403, 'msg': '答案和选项不能为空'})
            try:
                TestQuestions.objects.create(question_type=q_type, title=data['title'],
                                             answer=json.dumps(data['answer'], ensure_ascii=False))
                return JsonResponse(data={'code': 201, 'msg': '添加成功'})
            except Exception as e:
                return JsonResponse(data={'code': 401, 'msg': f'添加失败原因是{e}'})


class QuestionDetailView(View):
    @method_decorator(check_permission(['老师']))
    def get(self, request):
        q_type = QuestionType.objects.get(name=request.GET['question_type'])
        try:
            questions = TestQuestions.objects.filter(Q(question_type=q_type) & Q(is_delete=False)).all()
            questions_list = [{'title': i.title, 'options': i.options, 'answer': i.answer,
                               'question_type': i.question_type.id, 'add_time': i.add_time, 'id': i.id} for i in
                              questions]
            return JsonResponse(data={'code': 201, 'msg': '获取成功', 'data': questions_list})
        except Exception as e:
            return JsonResponse(data={'code': 403, 'msg': f'获取失败原因是{e}'})


class EditQuestion(View):
    @method_decorator(check_permission(['老师']))
    def get(self, request):
        try:
            q_id = request.GET.get('question_id')
        except:
            return JsonResponse({'code': 403, 'msg': 'id不存在'})
        try:
            question = TestQuestions.objects.get(id=q_id)
            return JsonResponse(data={'code': 201, 'msg': '获取成功', 'data': question.to_json()})
        except Exception as e:
            return JsonResponse(data={'code': 403, 'msg': f'获取失败原因是{e}'})

    @method_decorator(check_permission(['老师']))
    def put(self, request):
        data = json.loads(request.body)
        try:
            q_id = request.GET['question_id']
        except:
            return JsonResponse({'code': 403, 'msg': 'id不存在'})
        test_question = TestQuestions.objects.get(id=q_id)
        if not data['title']:
            return JsonResponse(data={'code': 401, 'msg': '标题不能为空'})
        test_question.title = data['title']
        if data['question_type'] == 1:
            if not all([data['answer'], data['options']]):
                return JsonResponse(data={'code': 403, 'msg': '答案和选项不能为空'})
            test_question.answer = json.dumps([data['answer']], ensure_ascii=False)
            test_question.options = json.dumps(data['options'], ensure_ascii=False)
        if data['question_type'] == 2:
            if not all([data['answers'], data['options']]):
                return JsonResponse(data={'code': 403, 'msg': '答案和选项不能为空'})
            test_question.answer = json.dumps(data['answers'], ensure_ascii=False)
            test_question.options = json.dumps(data['options'], ensure_ascii=False)
        if data['question_type'] in [3, 4]:
            if not all([data['answer']]):
                return JsonResponse(data={'code': 403, 'msg': '答案和选项不能为空'})
            test_question.answer = json.dumps(data['answer'], ensure_ascii=False)
        test_question.save()
        return JsonResponse(data={'code': 201, 'msg': '修改成功'})

    @method_decorator(check_permission(['老师']))
    def delete(self, request):
        try:
            q_id = request.GET['question_id']
        except:
            return JsonResponse({'code': 403, 'msg': 'id不存在'})
        try:
            test_question = TestQuestions.objects.get(id=q_id)
            test_question.is_delete = True
            test_question.save()
            return JsonResponse(data={'code': 201, 'msg': '删除成功'})
        except Exception as e:
            return JsonResponse(data={'code': 403, 'msg': f'删除失败原因是{e}'})


class GeneratePaper(View):
    @method_decorator(check_permission(['院长', '老师']))
    def get(self, request):
        teacher = Role.objects.get(name='院长')
        if teacher in User.objects.filter(username=request.user).first().roles.all():
            try:
                college = College.objects.get(college_dean=User.objects.get(username=request.user))
                questions_list = ExaminationPaper.objects.filter(college=college).all().values()
                return JsonResponse(data={'code': 201, 'msg': '获取成功', 'data': list(questions_list)})
            except Exception as e:
                return JsonResponse(data={'code': 403, 'msg': f'获取失败原因是{e}'})
        else:
            try:
                college = User.objects.filter(username=request.user).first().classes_user.first().colleges
                questions_list = ExaminationPaper.objects.filter(college=college).all().values()
                return JsonResponse(data={'code': 201, 'msg': '获取成功', 'data': list(questions_list)})
            except Exception as e:
                return JsonResponse(data={'code': 403, 'msg': f'获取失败原因是{e}'})

    @method_decorator(check_permission(['院长']))
    def put(self, request):
        user = User.objects.get(username=request.user)
        college = College.objects.get(college_dean=user)
        data = json.loads(request.body)
        date_range = data['date_range']
        questions_list = []
        answer_list = []
        for i in data['argument']:
            q_type = QuestionType.objects.get(name=i['title'])
            questions = TestQuestions.objects.filter(Q(question_type=q_type) & Q(is_delete=False)).all()
            if int(i['number']) > len(list(questions)):
                return JsonResponse({'code': 403, 'msg': f'{i["title"]}题目数量不能大于{len(list(questions))}'})
            selectable_list = sample(list(questions), int(i['number']))
            for j in selectable_list:
                questions_list.append(
                    {'id': j.id, 'title': j.title, 'options': j.options, 'question_type': j.question_type.name,
                     'score': i['score']})
                answer_list.append({'id': j.id, 'type': j.question_type.name, 'answer': j.answer})
        try:
            # s_time = str_to_time(date_range['start_time'], 'Asia/Shanghai')
            # e_time = str_to_time(date_range['end_time'], 'Asia/Shanghai')
            ExaminationPaper.objects.create(title=data['title'], questions_info=json.dumps(questions_list,
                                                                                           ensure_ascii=False),
                                            answer=json.dumps(answer_list, ensure_ascii=False), college=college,
                                            start_time=date_range['start_time'], end_time=date_range['end_time'])
            return JsonResponse({'code': 201, 'msg': 'ok!!!!!', 'data': questions_list})
        except Exception as e:
            return JsonResponse({'code': 403, 'msg': f'生成失败原因是{e}'})


def execute_raw_sql(sql):
    with connections['default'].cursor() as cursor:
        cursor.execute(sql)
        results = cursor.fetchall()
    return results


class ViewTestResult(View):
    @method_decorator(check_permission(['院长', '老师']))
    def get(self, request, p_id):
        classes = User.objects.filter(username=request.user).first().classes_user.all()
        all_user = []
        for i in classes:
            all_user.extend(i.user.all())
        all_test_result = TestResult.objects.filter(Q(examination_paper_id=p_id) & Q(answer_user__in=all_user)).all()
        correct_list = [{'answer_user': i.answer_user.username, 'test_paper': i.examination_paper.title,
                         'create_time': i.create_time, 'score': i.score, 'is_corrected': i.is_corrected,
                         'file_id': i.file_id, 'id': i.id} for i in all_test_result if not i.is_corrected]
        show_list = [
            {'answer_user': i.answer_user.username, 'test_paper': i.examination_paper.title,
             'create_time': i.create_time, 'score': i.score, 'is_corrected': i.is_corrected,
             'file_id': i.file_id, 'id': i.id} for i in all_test_result if i.is_corrected]
        return JsonResponse(data={'code': 201, 'msg': '获取成功', 'show_data': show_list, 'correct_data': correct_list})
